import 'dart:math';
import 'dart:ui';

import 'package:flutter/material.dart';

class LikeIcon extends StatefulWidget {
  final Offset offset;

  final Function(LikeIcon icon)? onComplete;

  const LikeIcon({
    super.key,
    this.offset = Offset.zero,
    this.onComplete,
  });

  @override
  State<StatefulWidget> createState() => _LikeIconState();
}

class _LikeIconState extends State<LikeIcon>
    with TickerProviderStateMixin {
  late AnimationController _animationController;
  late PathMetric _pathMetric;
  late Tangent? _tangent;

  /// 图标大小
  final double _size = 50;

  /// 结束高度，负值向上，正值向下
  final double _height = -200;
 
  /// 路径
  final Path _path = Path();

  /// 随机角度
  final double _angle = pi * Random().nextDouble() - pi / 2;

  final List<IconData> icons = const [Icons.favorite, Icons.thumb_up_alt, Icons.plus_one];
  final index = Random().nextInt(3);
  

  @override
  void initState() {
    _animationController =
        AnimationController(duration: const Duration(seconds: 3), vsync: this);
    Offset start = Offset.zero;

    /// 随机产生一个 正负值
    Offset end = Offset((Random().nextDouble() - 0.5) * 300, _height);

    _path.moveTo(start.dx, start.dy);

    Offset ctrl1 = (end - start) * 0.3;
    Offset ctrl2 = (-start + end) * 0.8;

    _path.cubicTo(ctrl1.dx, ctrl1.dy, ctrl2.dx, ctrl2.dy, end.dx, end.dy);

    PathMetrics pathMetrics = _path.computeMetrics();
    _pathMetric = pathMetrics.first;

    startAnimation();
    super.initState();
  }

  @override
  void dispose() {
    _animationController.dispose();
    super.dispose();
  }

  // 开始动画
  startAnimation() async {
    await _animationController.forward();
    widget.onComplete?.call(widget);
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
        left: widget.offset.dx - _size / 2,
        top: widget.offset.dy - _size,
        child: AnimatedBuilder(
          animation: _animationController,
          builder: _buildContent,
        ));
  }

  //获取动画的值
  double get value => _animationController.value;

  //获取动画的不透明度
  double get opacity {
    if (value < 0.1) {
      return 0.9 / 0.1 * value;
    }
    if (value < 0.8) {
      return 0.9;
    }
    var res = 0.9 - (value - 0.8) / (1 - 0.8);
    return res < 0 ? 0 : res;
  }

  //获取动画的缩放比例
  double get scale {
    if (value <= 0.5) {
      return 0.6 + value / 0.5 * 0.5;
    } else if (value <= 0.8) {
      return 1.1 * (1 / 1.1 + (1.1 - 1) / 1.1 * (value - 0.8) / 0.25);
    } else {
      return 1 + (value - 0.8) / 0.2 * 0.5;
    }
  }

  Widget _buildContent(BuildContext context, Widget? child) {
    _tangent = _pathMetric.getTangentForOffset(_pathMetric.length * value);

    return Transform(
      transform: Matrix4.translationValues(
          _tangent!.position.dx, _tangent!.position.dy, 0.0)
        ..rotateZ(_angle)
        ..scale(scale),
      alignment: Alignment.center,
      child: Opacity(
        opacity: opacity,
        child: Icon(
          icons[index],
          color: Colors.red,
          size: _size,
        ),
      ),
    );
  }
}
